package com.cpp.server.client;

import com.alibaba.fastjson.JSON;
import com.cpp.common.exception.BaseException;
import com.cpp.common.properties.XfPPtProperties;
import com.cpp.common.utils.ApiAuthAlgorithm;
import com.cpp.pojo.api.GeneratePPTApiResponse;
import com.cpp.pojo.api.PptProgressResponse;
import com.cpp.server.config.ApiConfig;
import lombok.RequiredArgsConstructor;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.springframework.core.io.ByteArrayResource;
import org.springframework.http.*;
import org.springframework.stereotype.Component;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;
import org.springframework.web.client.RestTemplate;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.Map;
@Slf4j
@Component
@RequiredArgsConstructor
public class PptGenerationClient {

    private final RestTemplate restTemplate;
    private final XfPPtProperties xfPPtProperties;
    private final ApiAuthAlgorithm apiAuthAlgorithm;
    private final ApiConfig apiConfig;
    /**
     * 根据 query 生成 PPT
     */
    public String generatePptByQuery(String query, String fileName, Map<String, Object> options) throws IOException {
        return generatePptInternal(query, null, null, fileName, options);
    }

//    /**
//     * 根据本地文件生成 PPT
//     */
//    public String generatePptByFile(File file, String fileName, Map<String, Object> options) throws IOException {
//        ByteArrayResource resource = new ByteArrayResource(readFileBytes(file)) {
//            @Override
//            public String getFilename() {
//                return file.getName();
//            }
//        };
//        return generatePptInternal(null, null, resource, fileName, options);
//    }
//
//    /**
//     * 根据远程文件 URL 生成 PPT
//     */
//    public String generatePptByFileUrl(String fileUrl, String fileName, Map<String, Object> options) {
//        return generatePptInternal(null, fileUrl, null, fileName, options);
//    }

    // 内部统一方法处理多种输入方式
    @SneakyThrows
    private String generatePptInternal(String query, String fileUrl, ByteArrayResource fileResource,
                                       String fileName, Map<String, Object> options) {
        long timestamp = System.currentTimeMillis()/1000;
        String signature = apiAuthAlgorithm.getSignature(xfPPtProperties.getAppId(), xfPPtProperties.getSecret(), timestamp );
//        request.setHeader("appId",appId);
//        request.setHeader("timestamp",str(timestamp));
//        request.setHeader("signature",signature);
        HttpHeaders headers = new HttpHeaders();
        headers.add("appId", xfPPtProperties.getAppId());
        headers.add("timestamp", String.valueOf(timestamp));
        headers.add("signature", signature);
        headers.setContentType(MediaType.MULTIPART_FORM_DATA);
        log.info("headers:{}",headers);

        MultiValueMap<String, Object> body = new LinkedMultiValueMap<>();

        if (query != null && !query.isEmpty()) {
            body.add("query", query);
        }

        if (fileUrl != null && !fileUrl.isEmpty()) {
            body.add("fileUrl", fileUrl);
        }

        if (fileResource != null) {
            body.add("file", fileResource);
        }

        body.add("fileName", fileName);

        // 添加其他可选参数
        for (Map.Entry<String, Object> entry : options.entrySet()) {
            if (entry.getValue() != null) {
                body.add(entry.getKey(), entry.getValue().toString());
            }
        }
        //  发送 POST 请求
        HttpEntity<MultiValueMap<String, Object>> requestEntity = new HttpEntity<>(body, headers);
        ResponseEntity<String> response = restTemplate.postForEntity(apiConfig.getAPI_URL(), requestEntity, String.class);
        log.info("body:{}",response.getBody());
        // 轮询检查 PPT 生成状态，直至成功或者失败
        String result = checkPptGeneration(headers, response.getBody());

        return result;
    }

    // 辅助方法：读取文件为字节数组
    private byte[] readFileBytes(File file) throws IOException {
        FileInputStream fis = new FileInputStream(file);
        byte[] bytes = new byte[(int) file.length()];
        fis.read(bytes);
        fis.close();
        return bytes;
    }

    // 可选：保存返回的 PPT 文件到本地
    public void savePptToFile(byte[] content, String outputPath) throws IOException {
        Path path = Paths.get(outputPath);
        Files.write(path, content);
    }

    //检查ppt生成
    public String checkPptGeneration(HttpHeaders headers, String body) throws InterruptedException {
        //处理一下请求头
        headers.remove("Content-Type");
        //读取json数据
        GeneratePPTApiResponse generatePPTApiResponse = JSON.parseObject(body, GeneratePPTApiResponse.class);
        //提取声明变量
        PptProgressResponse pptProgressResponse;
        ResponseEntity<String> response;
        HttpEntity<String> requestEntity = new HttpEntity<>(headers);
        //轮询检查ppt生成状态
        while (true) {
            response = restTemplate.exchange(
                    apiConfig.getPROGRESS_API_URL() + generatePPTApiResponse.getData().getSid(), // URL
                    HttpMethod.GET, // 请求方法
                    requestEntity, // 带请求头的请求体
                    String.class // 响应类型
            );
            log.info("body:{}",response.getBody());
            pptProgressResponse= JSON.parseObject(response.getBody(), PptProgressResponse.class);

            if (!pptProgressResponse.isFlag()||pptProgressResponse.getData().getPptStatus().equals("build_failed")){
                throw new BaseException("ppt生成失败");
            }
            if (pptProgressResponse.getData().getPptStatus().equals("done")){
                log.info("ppt生成完成");
                break;
            }
            //停止5秒
            Thread.sleep(5000);

        }
        return pptProgressResponse.getData().getPptUrl();
    }

}